
/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2017原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.support;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * Standalone XML application context, taking the context definition files
 * from the class path, interpreting plain paths as class path resource names
 * that include the package path (e.g. "mypackage/myresource.txt"). Useful for
 * test harnesses as well as for application contexts embedded within JARs.
 *
 * <p>The config location defaults can be overridden via {@link #getConfigLocations},
 * Config locations can either denote concrete files like "/myfiles/context.xml"
 * or Ant-style patterns like "/myfiles/*-context.xml" (see the
 * {@link org.springframework.util.AntPathMatcher} javadoc for pattern details).
 *
 * <p>Note: In case of multiple config locations, later bean definitions will
 * override ones defined in earlier loaded files. This can be leveraged to
 * deliberately override certain bean definitions via an extra XML file.
 *
 * <p><b>This is a simple, one-stop shop convenience ApplicationContext.
 * Consider using the {@link GenericApplicationContext} class in combination
 * with an {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}
 * for more flexible context setup.</b>
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see #getResource
 * @see #getResourceByPath
 * @see GenericApplicationContext
 */
/**
 *独立的XML应用程序上下文，采用上下文定义文件
 *从类路径，将普通路径解释为类路径资源名称
 *包括包路径（例如“mypackage/myresource.txt”）
 *测试工具以及嵌入JAR中的应用程序上下文。
 *
 *＜p＞配置位置默认值可以通过｛@link#getConfigLocations｝覆盖，
 *配置位置可以表示具体的文件，如“/myfiles/context.xml”
 *或Ant风格的模式，如“/myfiles/*-context.xml”（请参阅
 *｛@link org.springframework.util.AntPathMatcher｝获取模式详细信息的javadoc）。
 *
 *＜p＞注意：如果有多个配置位置，稍后的bean定义将
 *覆盖先前加载的文件中定义的。这可以用来
 *故意通过一个额外的XML文件覆盖某些bean定义。
 *
 *<p><b>这是一个简单的一站式便利应用程序上下文。
 *请考虑组合使用｛@link GenericApplicationContext｝类
 *使用｛@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader｝
 *以实现更灵活的上下文设置</b>
 *
 *@作者罗德·约翰逊
 *@作者Juergen Hoeller
 *@见#getResource
 *@参见#getResourceByPath
 *@参见GenericApplicationContext
 */
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {

	@Nullable
	private Resource[] configResources;


	/**
	 * Create a new ClassPathXmlApplicationContext for bean-style configuration.
	 * @see #setConfigLocation
	 * @see #setConfigLocations
	 * @see #afterPropertiesSet()
	 */
	/**
	 *为bean样式的配置创建一个新的ClassPathXmlApplicationContext。
	 *@参见#setConfigLocation
	 *@参见#setConfigLocations
	 *@参见#afterPropertiesSet（）
	 */
	public ClassPathXmlApplicationContext() {
	}

	/**
	 * Create a new ClassPathXmlApplicationContext for bean-style configuration.
	 * @param parent the parent context
	 * @see #setConfigLocation
	 * @see #setConfigLocations
	 * @see #afterPropertiesSet()
	 */
	/**
	 *为bean样式的配置创建一个新的ClassPathXmlApplicationContext。
	 *@param parent父上下文
	 *@参见#setConfigLocation
	 *@参见#setConfigLocations
	 *@参见#afterPropertiesSet（）
	 */
	public ClassPathXmlApplicationContext(ApplicationContext parent) {
		super(parent);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML file and automatically refreshing the context.
	 * @param configLocation resource location
	 * @throws BeansException if context creation failed
	 */
	/**
	 *创建一个新的ClassPathXmlApplicationContext，加载定义
	 *并自动刷新上下文。
	 *@param configLocation资源位置
	 *如果上下文创建失败，@throws BeansException
	 */
	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML files and automatically refreshing the context.
	 * @param configLocations array of resource locations
	 * @throws BeansException if context creation failed
	 */
	/**
	 *创建一个新的ClassPathXmlApplicationContext，加载定义
	 *并自动刷新上下文。
	 *@param configLocations资源位置数组
	 *如果上下文创建失败，@throws BeansException
	 */
	public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
		this(configLocations, true, null);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext with the given parent,
	 * loading the definitions from the given XML files and automatically
	 * refreshing the context.
	 * @param configLocations array of resource locations
	 * @param parent the parent context
	 * @throws BeansException if context creation failed
	 */
	/**
	 *使用给定的父级创建一个新的ClassPathXmlApplicationContext，
	 *从给定的XML文件加载定义，并自动
	 *刷新上下文。
	 *@param configLocations资源位置数组
	 *@param parent父上下文
	 *如果上下文创建失败，@throws BeansException
	 */
	public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)
			throws BeansException {

		this(configLocations, true, parent);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML files.
	 * @param configLocations array of resource locations
	 * @param refresh whether to automatically refresh the context,
	 * loading all bean definitions and creating all singletons.
	 * Alternatively, call refresh manually after further configuring the context.
	 * @throws BeansException if context creation failed
	 * @see #refresh()
	 */
	/**
	 *创建一个新的ClassPathXmlApplicationContext，加载定义
	 *从给定的XML文件。
	 *@param configLocations资源位置数组
	 *@param refresh是否自动刷新上下文，
	 *加载所有bean定义并创建所有singleton。
	 *或者，在进一步配置上下文之后手动调用刷新。
	 *如果上下文创建失败，@throws BeansException
	 *@见#refresh（）
	 */
	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
		this(configLocations, refresh, null);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext with the given parent,
	 * loading the definitions from the given XML files.
	 * @param configLocations array of resource locations
	 * @param refresh whether to automatically refresh the context,
	 * loading all bean definitions and creating all singletons.
	 * Alternatively, call refresh manually after further configuring the context.
	 * @param parent the parent context
	 * @throws BeansException if context creation failed
	 * @see #refresh()
	 */
	/**
	 *使用给定的父级创建一个新的ClassPathXmlApplicationContext，
	 *从给定的XML文件加载定义。
	 *@param configLocations资源位置数组
	 *@param refresh是否自动刷新上下文，
	 *加载所有bean定义并创建所有singleton。
	 *或者，在进一步配置上下文之后手动调用刷新。
	 *@param parent父上下文
	 *如果上下文创建失败，@throws BeansException
	 *@见#refresh（）
	 */
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}


	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML file and automatically refreshing the context.
	 * <p>This is a convenience method to load class path resources relative to a
	 * given Class. For full flexibility, consider using a GenericApplicationContext
	 * with an XmlBeanDefinitionReader and a ClassPathResource argument.
	 * @param path relative (or absolute) path within the class path
	 * @param clazz the class to load resources with (basis for the given paths)
	 * @throws BeansException if context creation failed
	 * @see org.springframework.core.io.ClassPathResource#ClassPathResource(String, Class)
	 * @see org.springframework.context.support.GenericApplicationContext
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	/**
	 *创建一个新的ClassPathXmlApplicationContext，加载定义
	 *并自动刷新上下文。
	 *＜p＞这是一种相对于
	 *给定类别。为了获得充分的灵活性，可以考虑使用GenericApplicationContext
	 *带有XmlBeanDefinitionReader和ClassPathResource参数。
	 *@param path类路径中的相对（或绝对）路径
	 *@param clazz加载资源的类（给定路径的基础）
	 *如果上下文创建失败，@throws BeansException
	 *@see org.springframework.core.io.ClassPathResource#ClassPathResource（字符串，类）
	 *@请参阅org.springframework.context.support.GenericApplicationContext
	 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	public ClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException {
		this(new String[] {path}, clazz);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML files and automatically refreshing the context.
	 * @param paths array of relative (or absolute) paths within the class path
	 * @param clazz the class to load resources with (basis for the given paths)
	 * @throws BeansException if context creation failed
	 * @see org.springframework.core.io.ClassPathResource#ClassPathResource(String, Class)
	 * @see org.springframework.context.support.GenericApplicationContext
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	/**
	 *创建一个新的ClassPathXmlApplicationContext，加载定义
	 *并自动刷新上下文。
	 *@param paths类路径中相对（或绝对）路径的数组
	 *@param clazz加载资源的类（给定路径的基础）
	 *如果上下文创建失败，@throws BeansException
	 *@see org.springframework.core.io.ClassPathResource#ClassPathResource（字符串，类）
	 *@请参阅org.springframework.context.support.GenericApplicationContext
	 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz) throws BeansException {
		this(paths, clazz, null);
	}

	/**
	 * Create a new ClassPathXmlApplicationContext with the given parent,
	 * loading the definitions from the given XML files and automatically
	 * refreshing the context.
	 * @param paths array of relative (or absolute) paths within the class path
	 * @param clazz the class to load resources with (basis for the given paths)
	 * @param parent the parent context
	 * @throws BeansException if context creation failed
	 * @see org.springframework.core.io.ClassPathResource#ClassPathResource(String, Class)
	 * @see org.springframework.context.support.GenericApplicationContext
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	/**
	 *使用给定的父级创建一个新的ClassPathXmlApplicationContext，
	 *从给定的XML文件加载定义，并自动
	 *刷新上下文。
	 *@param paths类路径中相对（或绝对）路径的数组
	 *@param clazz加载资源的类（给定路径的基础）
	 *@param parent父上下文
	 *如果上下文创建失败，@throws BeansException
	 *@see org.springframework.core.io.ClassPathResource#ClassPathResource（字符串，类）
	 *@请参阅org.springframework.context.support.GenericApplicationContext
	 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		Assert.notNull(paths, "Path array must not be null");
		Assert.notNull(clazz, "Class argument must not be null");
		this.configResources = new Resource[paths.length];
		for (int i = 0; i < paths.length; i++) {
			this.configResources[i] = new ClassPathResource(paths[i], clazz);
		}
		refresh();
	}


	@Override
	@Nullable
	protected Resource[] getConfigResources() {
		return this.configResources;
	}

}
